home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / png / pnglib06 / example.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-01  |  8.6 KB  |  308 lines

  1. /* example.c - an example of using pnglib */
  2.  
  3. /* this is an example of how to use pnglib to read and write
  4.    png files.  The file pnglib.txt is much more verbose then
  5.    this.  If you have not read it, do so first.  This was
  6.    designed to be a starting point of an implementation.
  7.    This is not officially part of pnglib, and therefore
  8.    does not require a copyright notice.
  9.    */
  10.  
  11. #include "png.h"
  12.  
  13. /* read a png file */
  14. void read_png(char *file_name)
  15. {
  16.    FILE *fp;
  17.    png_struct *png_ptr;
  18.    png_info *info_ptr;
  19.  
  20.    /* open the file */
  21.    fp = fopen(file_name, "rb");
  22.    if (!fp)
  23.       return;
  24.  
  25.    /* allocate the necessary structures */
  26.    png_ptr = malloc(sizeof (png_struct));
  27.    info_ptr = malloc(sizeof (png_info));
  28.  
  29.    /* set error handling */
  30.    if (setjmp(png_ptr->jmpbuf))
  31.    {
  32.       /* If we get here, we had a problem reading the file */
  33.       return;
  34.    }
  35.  
  36.    /* initialize the structures */
  37.    png_read_init(png_ptr);
  38.    png_info_init(info_ptr);
  39.  
  40.    /* set up the input control */
  41.    png_init_io(png_ptr, fp);
  42.  
  43.    /* read the file information */
  44.    png_read_info(png_ptr, info_ptr);
  45.  
  46.    /* allocate the memory to hold the image using the fields
  47.       of png_info. */
  48.  
  49.    /* set up the transformations you want.  Note that these are
  50.       all optional.  Only call them if you want them */
  51.  
  52.    /* expand paletted colors into true rgb */
  53.    if (png_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  54.       png_info->bit_depth < 8)
  55.       png_set_expand(png_ptr);
  56.  
  57.    /* expand grayscale images to the full 8 bits */
  58.    if (png_info->color_type == PNG_COLOR_TYPE_GRAY &&
  59.       png_info->bit_depth < 8)
  60.       png_set_expand(png_ptr);
  61.  
  62.    /* expand images with transparency to full alpha channels */
  63.    if (png_info->valid & PNG_INFO_tRNS)
  64.       png_set_expand(png_ptr);
  65.  
  66.    /* Set the background color to draw transparent and alpha
  67.       images over */
  68.  
  69.    if (png_info->valid & PNG_INFO_bKGD)
  70.       png_set_backgrond(png_ptr, png_info->background);
  71.    else
  72.    {
  73.       png_uint_16 my_backgound[3];
  74.       png_set_background(png_ptr, &my_background);
  75.    }
  76.  
  77.    /* tell pnglib to handle the gamma conversion for you */
  78.    if (png_info->valid & PNG_INFO_gAMA)
  79.       png_set_gamma(png_ptr, screen_gamma, png_info->gamma);
  80.    else
  81.       png_set_gamma(png_ptr, screen_gamma, 0.45);
  82.  
  83.    /* tell pnglib to strip 16 bit depth files down to 8 bits */
  84.    if (png_info->bit_depth == 16)
  85.       png_set_strip_16(png_ptr);
  86.  
  87.    /* dither rgb files down to 8 bit palettes &*/
  88.    if (png_info->color_type == PNG_COLOR_TYPE_RGB ||
  89.       png_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  90.    {
  91.       if (png_info->valid & PNG_INFO_PLTE)
  92.          png_set_dither(png_ptr, png_info->palette,
  93.             png_info->num_palette, 256, png_info->histogram);
  94.       else
  95.       {
  96.          png_color std_color_cube[256] = { ... colors ... };
  97.  
  98.          png_set_dither(png_ptr, std_color_cube, 256, 256, NULL);
  99.       }
  100.    }
  101.  
  102.    /* invert monocrome files */
  103.    if (png_info->bit_depth == 1 &&
  104.       png_info->color_type == PNG_COLOR_GRAY)
  105.       png_set_invert(png_ptr);
  106.  
  107.    /* shift the pixels down to their true bit depth */
  108.    if (png_info->valid & PNG_INFO_sBIT &&
  109.       png_info->bit_depth > png_info->sig_bit)
  110.       png_set_shift(png_ptr, png_info->sig_bit);
  111.  
  112.    /* pack pixels into bytes */
  113.    if (png_info->bit_depth < 8)
  114.       png_set_packing(png_ptr);
  115.  
  116.    /* flip the rgb pixels to bgr */
  117.    if (png_info->color_type == PNG_COLOR_TYPE_RGB ||
  118.       png_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  119.       png_set_bgr(png_ptr);
  120.  
  121.    /* swap bytes of 16 bit files to least significant bit first */
  122.    if (png_info->bit_depth == 16)
  123.       png_set_swap(png_ptr);
  124.  
  125.    /* add a filler byte to store rgb files as rgbx */
  126.    if (png_info->bit_depth == 8 &&
  127.       png_info->color_type == PNG_COLOR_TYPE_RGB)
  128.       png_set_rgbx(png_ptr);
  129.  
  130.    /* optional call to update palette with transformations */
  131.    void png_start_read_image(png_ptr);
  132.  
  133.    /* the easiest way to read the image */
  134.    void *row_pointers[height];
  135.    png_read_image(png_ptr, row_pointers);
  136.  
  137.    /* the other way to read images - deal with interlacing */
  138.  
  139.    /* turn on interlace handling */
  140.    if (png_info->interlace_type)
  141.       number_passes = png_set_interlace_handling(png_ptr);
  142.    else
  143.       number_passes = 1;
  144.  
  145.    for (pass = 0; pass < number_passes; pass++)
  146.    {
  147.       /* Read the image using the "sparkle" effect. */
  148.       png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
  149.  
  150.       /* If you are only reading on row at a time, this works */
  151.       for (y = 0; y < height; y++)
  152.       {
  153.          char *row_pointers = row[y];
  154.          png_read_rows(png_ptr, &row_pointers, NULL, 1);
  155.       }
  156.  
  157.       /* to get the rectangle effect, use the third parameter */
  158.       png_read_rows(png_ptr, NULL, row_pointers, number_of_rows);
  159.  
  160.       /* if you have called png_set_alpha(), and you want the
  161.          rectangle effect, you will need to pass two sets of
  162.          rows. */
  163.       png_read_rows(png_ptr, row_pointers, display_pointers,
  164.          number_of_rows);
  165.  
  166.       /* if you want to display the image after every pass, do
  167.          so here */
  168.    }
  169.  
  170.    /* read the rest of the file, getting any additional chunks
  171.       in png_info */
  172.    png_read_end(png_ptr, png_info);
  173.  
  174.    /* clean up after the read, and free any memory allocated */
  175.    png_read_distroy(png_ptr, png_info);
  176.  
  177.    /* free the structures */
  178.    free(png_ptr);
  179.    free(png_info);
  180.  
  181.    /* close the file */
  182.    fclose(fp);
  183.  
  184.    /* that's it */
  185.    return;
  186. }
  187.  
  188. /* write a png file */
  189. void write_png(char *file_name, ... other image information ...)
  190. {
  191.    FILE *fp;
  192.    png_struct *png_ptr;
  193.    png_info *info_ptr;
  194.  
  195.    /* open the file */
  196.    fp = fopen(file_name, "wb");
  197.    if (!fp)
  198.       return;
  199.  
  200.    /* allocate the necessary structures */
  201.    png_ptr = malloc(sizeof (png_struct));
  202.    info_ptr = malloc(sizeof (png_info));
  203.  
  204.    /* set error handling */
  205.    if (setjmp(png_ptr->jmpbuf))
  206.    {
  207.       /* If we get here, we had a problem reading the file */
  208.       return;
  209.    }
  210.  
  211.    /* initialize the structures */
  212.    png_write_init(png_ptr);
  213.    png_info_init(info_ptr);
  214.  
  215.    /* set up the output control */
  216.    png_init_io(png_ptr, fp);
  217.  
  218.    /* set the file information here */
  219.    info_ptr->width = ;
  220.    info_ptr->height = ;
  221.    etc.
  222.  
  223.    /* set the palette if there is one */
  224.    png_info->valid |= PNG_INFO_PLTE;
  225.    png_info->palette = malloc(256 * sizeof (png_color));
  226.    png_info->num_palette = 256;
  227.    ... set palette colors ...
  228.  
  229.    /* optional significant bit chunk */
  230.    png_info->valid |= PNG_INFO_sBIT;
  231.    png_info->sig_bit = true_bit_depth;
  232.  
  233.    /* optional gamma chunk */
  234.    png_info->valid |= PNG_INFO_gAMA;
  235.    png_info->gamma = gamma;
  236.  
  237.    /* write the file information */
  238.    png_write_info(png_ptr, info_ptr);
  239.  
  240.    /* set up the transformations you want.  Note that these are
  241.       all optional.  Only call them if you want them */
  242.  
  243.    /* invert monocrome pixels */
  244.    png_set_invert(png_ptr);
  245.  
  246.    /* shift the pixels up to a legal bit depth and fill in
  247.       as appropriate to correctly scale the image */
  248.    png_set_shift(png_ptr, png_info->sig_bit);
  249.  
  250.    /* pack pixels into bytes */
  251.    png_set_packing(png_ptr);
  252.  
  253.    /* flip bgr pixels to rgb */
  254.    png_set_bgr(png_ptr);
  255.  
  256.    /* swap bytes of 16 bit files to most significant bit first */
  257.    png_set_swap(png_ptr);
  258.  
  259.    /* get rid of filler bytes, pack rgb into 3 bytes */
  260.    png_set_rgbx(png_ptr);
  261.  
  262.    /* the easiest way to write the image */
  263.    void *row_pointers[height];
  264.    png_write_image(png_ptr, row_pointers);
  265.  
  266.    /* the other way to write the image - deal with interlacing */
  267.  
  268.    /* turn on interlace handling */
  269.    if (interlacing)
  270.       number_passes = png_set_interlace_handling(png_ptr);
  271.    else
  272.       number_passes = 1;
  273.  
  274.    for (pass = 0; pass < number_passes; pass++)
  275.    {
  276.       /* Write a few rows at a time. */
  277.       png_write_rows(png_ptr, row_pointers, number_of_rows);
  278.  
  279.       /* If you are only writing one row at a time, this works */
  280.       for (y = 0; y < height; y++)
  281.       {
  282.          char *row_pointers = row[y];
  283.          png_write_rows(png_ptr, &row_pointers, 1);
  284.       }
  285.    }
  286.  
  287.    /* write the rest of the file */
  288.    png_write_end(png_ptr, png_info);
  289.  
  290.    /* clean up after the write, and free any memory allocated */
  291.    png_write_distroy(png_ptr);
  292.  
  293.    /* if you malloced the palette, free it here */
  294.    if (png_ptr->palette)
  295.       free(png_ptr->palette);
  296.  
  297.    /* free the structures */
  298.    free(png_ptr);
  299.    free(png_info);
  300.  
  301.    /* close the file */
  302.    fclose(fp);
  303.  
  304.    /* that's it */
  305.    return;
  306. }
  307.  
  308.